﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BreakdownsViewModel.cs" company="Mar3ek">
//   http://mar3ek.wordpress.com
// </copyright>
// <summary>
//   Defines the BreakdownsViewModel type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Mar3ek.ColorHatTimeTracker.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.CompilerServices;

    using ColorhatNet;

    using Mar3ek.ColorHatTimeTracker.Annotations;

    /// <summary>
    /// The breakdowns view model.
    /// </summary>
    public class BreakdownsViewModel : INotifyPropertyChanged
    {
        /// <summary>
        /// Stores the time entries grouped by customer.
        /// </summary>
        private ObservableCollection<KeyValuePair<double, string>> breakdownByCustomer = new ObservableCollection<KeyValuePair<double, string>>();

        /// <summary>
        /// Stores the time entries grouped by project.
        /// </summary>
        private ObservableCollection<KeyValuePair<double, string>> breakdownByProject = new ObservableCollection<KeyValuePair<double, string>>();

        /// <summary>
        /// Stores the time entries grouped by service.
        /// </summary>
        private ObservableCollection<KeyValuePair<double, string>> breakdownByService = new ObservableCollection<KeyValuePair<double, string>>();

        /// <summary>
        /// Stores the time span.
        /// </summary>
        private string timeSpanField;

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Gets or sets the breakdown by customer.
        /// </summary>
        public ObservableCollection<KeyValuePair<double, string>> BreakdownByCustomer
        {
            get
            {
                return this.breakdownByCustomer;
            }

            set
            {
                this.breakdownByCustomer = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the breakdown by project.
        /// </summary>
        public ObservableCollection<KeyValuePair<double, string>> BreakdownByProject
        {
            get
            {
                return this.breakdownByProject;
            }

            set
            {
                this.breakdownByProject = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the breakdown by service.
        /// </summary>
        public ObservableCollection<KeyValuePair<double, string>> BreakdownByService
        {
            get
            {
                return this.breakdownByService;
            }

            set
            {
                this.breakdownByService = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Gets or sets the time span.
        /// </summary>
        public string TimeSpan
        {
            get
            {
                return this.timeSpanField;
            }

            set
            {
                if (value == this.timeSpanField)
                {
                    return;
                }

                this.timeSpanField = value;
                this.OnPropertyChanged();
            }
        }

        /// <summary>
        /// Initializes this view model.
        /// </summary>
        /// <param name="timeEntries">
        /// The time entries to break down.
        /// </param>
        /// <param name="timeSpan">
        /// The time span.
        /// </param>
        public void Initialize(IEnumerable<TimeEntry> timeEntries, string timeSpan)
        {
            this.TimeSpan = timeSpan;

            // ReSharper disable PossibleMultipleEnumeration
            var breakByCustomer = timeEntries.GroupBy(te => te.Customer).Select(g => new KeyValuePair<double, string>(Math.Round(g.Sum(te => te.Duration.TotalHours), 2), g.Key)).ToList();
            var breakByProject = timeEntries.GroupBy(te => te.Project).Select(g => new KeyValuePair<double, string>(Math.Round(g.Sum(te => te.Duration.TotalHours), 2), g.Key)).ToList();
            var breakByService = timeEntries.GroupBy(te => te.Service).Select(g => new KeyValuePair<double, string>(Math.Round(g.Sum(te => te.Duration.TotalHours), 2), g.Key)).ToList();
            // ReSharper restore PossibleMultipleEnumeration
            BreakdownByCustomer = new ObservableCollection<KeyValuePair<double, string>>(breakByCustomer);
            BreakdownByProject = new ObservableCollection<KeyValuePair<double, string>>(breakByProject);
            BreakdownByService = new ObservableCollection<KeyValuePair<double, string>>(breakByService);
        }

        /// <summary>
        /// The property changed event invocator.
        /// </summary>
        /// <param name="propertyName">
        /// The property name.
        /// </param>
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
